@karinjs/adapter-qqbot 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +222 -766
- package/dist/apps/login.d.ts +20 -0
- package/dist/apps/login.js +57 -0
- package/dist/config-H7LrvlNU.js +197 -0
- package/dist/index.d.ts +589 -418
- package/dist/index.js +2844 -97
- package/dist/onboard-BX8g8Wik.js +249 -0
- package/dist/utils-DO4gEkVN.js +3 -0
- package/dist/web.config.d.ts +20 -23
- package/dist/web.config.js +170 -221
- package/package.json +24 -18
- package/dist/chunk-PYOUSZ6B.js +0 -1501
package/README.md
CHANGED
|
@@ -1,870 +1,326 @@
|
|
|
1
1
|
# @karinjs/adapter-qqbot
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@karinjs/adapter-qqbot)
|
|
4
|
+
[](./LICENSE)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
为 [Karin](https://github.com/KarinJS/Karin) 框架提供 QQ 官方机器人接入能力。
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- ✅ 支持 WebSocket 和 Webhook 两种连接方式
|
|
11
|
-
- ✅ 支持多种 Markdown 模板(原生、图文模板、纯文模板)
|
|
12
|
-
- ✅ 支持沙盒环境和正式环境
|
|
13
|
-
- ✅ 完整的 TypeScript 类型定义
|
|
14
|
-
- ✅ 自动消息签名验证
|
|
8
|
+
> **2.0 已发布**:完整重写,对齐 QQ 开放平台 2026 年起的新事件协议
|
|
9
|
+
> (`GROUP_MESSAGE_CREATE` 全量群聊消息 + `mentions` 数组),并适配
|
|
10
|
+
> Markdown / Keyboard 全量开放后的发送方式。
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
### 使用 pnpm(推荐)
|
|
12
|
+
---
|
|
19
13
|
|
|
20
|
-
|
|
21
|
-
pnpm add @karinjs/adapter-qqbot -w
|
|
22
|
-
```
|
|
14
|
+
## 特性
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
- 🌐 **完整事件支持**:群聊(@/全量)、单聊、频道、频道私信、按钮点击、机器人入退群、主动消息开关
|
|
17
|
+
- 📨 **双发送通道**:自动选择「经典通道」(text + media)或「Markdown 通道」(msg_type=2 + keyboard),按消息内容与配置开关
|
|
18
|
+
- 🔌 **双接入方式**:WebSocket(推荐,无需公网)/ Webhook(QQ 主动推送)
|
|
19
|
+
- ♻️ **WebSocket Resume**:断网自动重连,携带 `session_id` / `seq` 通过 `op:6` 恢复,减少消息丢失
|
|
20
|
+
- 🔑 **扫码登录**:插件首次启动自动二维码引导,授权后写回 `config.json`
|
|
21
|
+
- 🧩 **按钮回调**:完整接入 `INTERACTION_CREATE`,自动 ack 并以普通消息事件投递给业务层
|
|
22
|
+
- 🛡️ **签名校验**:webhook 入口自动用 ed25519 校验
|
|
23
|
+
- 📐 **完整 TypeScript 类型**
|
|
24
|
+
- 🧹 **零 1.x 残留**:不再依赖 Markdown 模板 / keyboard 模板 / 中转服务
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
npm install @karinjs/adapter-qqbot
|
|
28
|
-
```
|
|
26
|
+
---
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
## 安装
|
|
31
29
|
|
|
32
30
|
```bash
|
|
33
|
-
|
|
31
|
+
pnpm add @karinjs/adapter-qqbot
|
|
34
32
|
```
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
> 要求 Node.js >= 18,Karin >= 1.15
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
---
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
- Node.js >= 16
|
|
42
|
-
- 有QQ开放平台的机器人应用
|
|
43
|
-
|
|
44
|
-
### 5分钟快速配置
|
|
45
|
-
|
|
46
|
-
1. **安装插件**
|
|
47
|
-
```bash
|
|
48
|
-
pnpm add @karinjs/adapter-qqbot -w
|
|
49
|
-
```
|
|
38
|
+
## 快速开始
|
|
50
39
|
|
|
51
|
-
|
|
52
|
-
- 访问 [QQ开放平台](https://bot.q.qq.com/)
|
|
53
|
-
- 创建机器人应用,获取 AppID 和 Secret
|
|
40
|
+
### 方式 A:扫码登录(推荐)
|
|
54
41
|
|
|
55
|
-
|
|
56
|
-
```json
|
|
57
|
-
[
|
|
58
|
-
{
|
|
59
|
-
"appId": "你的AppID",
|
|
60
|
-
"secret": "你的Secret",
|
|
61
|
-
"event": { "type": 1 }
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
```
|
|
42
|
+
启动后没有任何已配置的 QQBot 时,控制台只打印一行提示:
|
|
65
43
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
44
|
+
```
|
|
45
|
+
==========================================
|
|
46
|
+
未检测到 QQBot 配置
|
|
47
|
+
请使用任意可用 bot(如 OneBot / Console 适配器)
|
|
48
|
+
对机器人发送指令: #QQ登录
|
|
49
|
+
扫码授权完成后会自动写入配置并完成初始化
|
|
70
50
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```
|
|
51
|
+
⚠ 注意:扫码授权会刷新该机器人的 secret,旧 secret 立即失效
|
|
52
|
+
==========================================
|
|
53
|
+
```
|
|
75
54
|
|
|
76
|
-
|
|
55
|
+
按提示,在**任意已连接的 bot 适配器**(OneBot、Console、Discord …)下,给机器人发送:
|
|
77
56
|
|
|
78
|
-
|
|
57
|
+
```
|
|
58
|
+
#QQ登录 # 或 #qq登录 / #qqlogin / #QQLogin
|
|
59
|
+
```
|
|
79
60
|
|
|
80
|
-
|
|
61
|
+
服务端控制台随后弹出 ASCII 二维码:
|
|
81
62
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
63
|
+
```
|
|
64
|
+
▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢
|
|
65
|
+
▢ ASCII QR ▢▢▢▢▢▢▢
|
|
66
|
+
▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢▢
|
|
86
67
|
|
|
87
|
-
|
|
68
|
+
请使用 QQ 扫描上方二维码,或在手机 QQ 打开链接:
|
|
69
|
+
https://q.qq.com/qqbot/openclaw/connect.html?task_id=...
|
|
70
|
+
```
|
|
88
71
|
|
|
89
|
-
|
|
72
|
+
手机 QQ 扫码授权后,插件自动:
|
|
90
73
|
|
|
91
|
-
|
|
74
|
+
1. 从平台拉取 `appId` + 加密的 `secret`
|
|
75
|
+
2. 本地 AES-256-GCM 解密
|
|
76
|
+
3. 调 `/users/@me` 获取昵称
|
|
77
|
+
4. 写入 `${karin-base}/@karinjs-adapter-qqbot/config/config.json`
|
|
78
|
+
5. `watch` 回调自动初始化 bot,无需重启
|
|
92
79
|
|
|
93
|
-
|
|
80
|
+
> 该指令同样可用于**新增账号**和**刷新已有账号的 secret**。
|
|
94
81
|
|
|
95
|
-
|
|
82
|
+
### 方式 B:手动配置
|
|
96
83
|
|
|
97
|
-
|
|
98
|
-
[
|
|
99
|
-
{
|
|
100
|
-
"appId": "你的机器人AppID",
|
|
101
|
-
"secret": "你的机器人Secret"
|
|
102
|
-
}
|
|
103
|
-
]
|
|
104
|
-
```
|
|
84
|
+
在 [QQ 开放平台](https://bot.q.qq.com/) 创建机器人,记录 `AppID` 与 `Secret`,然后编辑:
|
|
105
85
|
|
|
106
|
-
|
|
86
|
+
`@karinjs/adapter-qqbot/config/config.json`:
|
|
107
87
|
|
|
108
88
|
```json
|
|
109
89
|
[
|
|
110
90
|
{
|
|
111
|
-
"
|
|
112
|
-
"
|
|
91
|
+
"name": "我的机器人",
|
|
92
|
+
"appId": "1234567890",
|
|
93
|
+
"secret": "your-secret",
|
|
113
94
|
"prodApi": "https://api.sgroup.qq.com",
|
|
114
95
|
"sandboxApi": "https://sandbox.api.sgroup.qq.com",
|
|
115
|
-
"tokenApi": "",
|
|
96
|
+
"tokenApi": "https://bots.qq.com/app/getAppAccessToken",
|
|
116
97
|
"sandbox": false,
|
|
117
98
|
"qqEnable": true,
|
|
118
99
|
"guildEnable": true,
|
|
119
100
|
"guildMode": 0,
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"rep": "#"
|
|
125
|
-
}
|
|
126
|
-
],
|
|
127
|
-
"markdown": {
|
|
128
|
-
"mode": 0,
|
|
129
|
-
"id": "",
|
|
130
|
-
"kv": [
|
|
131
|
-
"text_start",
|
|
132
|
-
"img_dec",
|
|
133
|
-
"img_url",
|
|
134
|
-
"text_end"
|
|
135
|
-
]
|
|
136
|
-
},
|
|
137
|
-
"event": {
|
|
138
|
-
"type": 1,
|
|
139
|
-
"wsUrl": "",
|
|
140
|
-
"wsToken": ""
|
|
141
|
-
}
|
|
101
|
+
"regex": [{ "reg": "^/", "rep": "#" }],
|
|
102
|
+
"markdown": { "enable": false },
|
|
103
|
+
"keyboard": { "enable": true },
|
|
104
|
+
"event": { "type": 2 }
|
|
142
105
|
}
|
|
143
106
|
]
|
|
144
107
|
```
|
|
145
108
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
#### 方式一:Webhook(推荐)
|
|
149
|
-
|
|
150
|
-
**适用场景:** 有公网IP或域名的服务器
|
|
151
|
-
|
|
152
|
-
1. 在配置文件中设置:
|
|
153
|
-
```json
|
|
154
|
-
{
|
|
155
|
-
"event": {
|
|
156
|
-
"type": 1
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
2. 在QQ开放平台配置回调地址:
|
|
162
|
-
- 回调地址格式:`https://你的域名/qqbot/webhook`
|
|
163
|
-
- 例如:`https://your-domain.com/qqbot/webhook`
|
|
164
|
-
- **⚠️ 重要限制:**
|
|
165
|
-
- 必须使用 **HTTPS** 协议
|
|
166
|
-
- 端口必须为 **443**(标准HTTPS端口)
|
|
167
|
-
- 不支持自定义端口(如:8080、:3000等)
|
|
168
|
-
|
|
169
|
-
> **重要说明:** 这是**统一的回调地址**,QQ开放平台会将所有配置的事件类型(群聊、C2C私聊、频道消息等)都发送到这个地址。您不需要为不同的消息类型配置不同的回调地址。
|
|
170
|
-
|
|
171
|
-
#### 方式二:WebSocket
|
|
172
|
-
|
|
173
|
-
**适用场景:** 内网环境,需要通过中转服务连接
|
|
174
|
-
|
|
175
|
-
1. 在配置文件中设置:
|
|
176
|
-
```json
|
|
177
|
-
{
|
|
178
|
-
"event": {
|
|
179
|
-
"type": 2,
|
|
180
|
-
"wsUrl": "wss://your-websocket-server/ws",
|
|
181
|
-
"wsToken": "你的ws认证token"
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### 第五步:反向代理配置(重要)
|
|
187
|
-
|
|
188
|
-
> **为什么需要反向代理?**
|
|
189
|
-
>
|
|
190
|
-
> QQ开放平台对Webhook回调地址有严格要求:
|
|
191
|
-
> - **必须使用HTTPS协议**(不支持HTTP)
|
|
192
|
-
> - **端口必须为443**(标准HTTPS端口,不支持自定义端口)
|
|
193
|
-
> - 必须有有效的SSL证书
|
|
194
|
-
>
|
|
195
|
-
> 如果你的Karin服务运行在:
|
|
196
|
-
> - 内网服务器(如家用电脑、局域网服务器)
|
|
197
|
-
> - 云服务器的内网端口(如3000端口)
|
|
198
|
-
> - Docker容器内部
|
|
199
|
-
>
|
|
200
|
-
> 就需要通过反向代理将内网服务暴露到公网的443端口,并配置SSL证书。
|
|
201
|
-
|
|
202
|
-
#### 反向代理的目标
|
|
109
|
+
保存即生效(`watch` 自动重载)。
|
|
203
110
|
|
|
204
|
-
|
|
111
|
+
---
|
|
205
112
|
|
|
206
|
-
|
|
207
|
-
- 群聊消息(GROUP_AT_MESSAGE_CREATE)
|
|
208
|
-
- C2C私聊消息(C2C_MESSAGE_CREATE)
|
|
209
|
-
- 频道消息(GUILD_MESSAGE_CREATE)
|
|
210
|
-
- 频道私信(DIRECT_MESSAGE_CREATE)
|
|
211
|
-
- 其他机器人事件
|
|
113
|
+
## 配置项详解
|
|
212
114
|
|
|
213
|
-
|
|
115
|
+
| 字段 | 类型 | 默认 | 说明 |
|
|
116
|
+
| --- | --- | --- | --- |
|
|
117
|
+
| `name` | string | `""` | 机器人显示名(扫码登录会自动获取) |
|
|
118
|
+
| `appId` | string | — | 机器人 AppID(**必填**) |
|
|
119
|
+
| `secret` | string | — | 机器人 Secret(**必填**) |
|
|
120
|
+
| `prodApi` | string | `https://api.sgroup.qq.com` | 正式环境 API 基址 |
|
|
121
|
+
| `sandboxApi` | string | `https://sandbox.api.sgroup.qq.com` | 沙盒环境 API 基址 |
|
|
122
|
+
| `tokenApi` | string | `https://bots.qq.com/app/getAppAccessToken` | access_token 获取接口 |
|
|
123
|
+
| `sandbox` | boolean | `false` | 是否启用沙盒环境 |
|
|
124
|
+
| `qqEnable` | boolean | `true` | 是否处理单聊 / 群聊 |
|
|
125
|
+
| `guildEnable` | boolean | `true` | 是否处理频道消息 |
|
|
126
|
+
| `guildMode` | `0` \| `1` | `0` | `0` 公域(只接 @ 消息)/ `1` 私域(所有消息) |
|
|
127
|
+
| `regex` | object[] | `[{reg:"^/", rep:"#"}]` | 收到消息后对文本执行的正则替换 |
|
|
128
|
+
| `keyboard.enable` | boolean | `true` | 是否将文本中的 URL **自动**转为 keyboard 按钮 |
|
|
129
|
+
| `event.type` | `0` \| `1` \| `2` | `2` | 事件接收方式:0 关闭 / 1 webhook / 2 WebSocket |
|
|
214
130
|
|
|
215
|
-
|
|
131
|
+
---
|
|
216
132
|
|
|
217
|
-
|
|
218
|
-
```bash
|
|
219
|
-
# Ubuntu/Debian
|
|
220
|
-
sudo apt update && sudo apt install nginx
|
|
133
|
+
## 事件接收方式
|
|
221
134
|
|
|
222
|
-
|
|
223
|
-
sudo yum install nginx
|
|
224
|
-
```
|
|
135
|
+
### WebSocket(推荐,`event.type: 2`)
|
|
225
136
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
server {
|
|
232
|
-
listen 80;
|
|
233
|
-
server_name your-domain.com; # 替换为你的域名或公网IP
|
|
234
|
-
|
|
235
|
-
# QQ机器人webhook接收地址
|
|
236
|
-
location /qqbot/webhook {
|
|
237
|
-
# 代理到本地Karin服务
|
|
238
|
-
proxy_pass http://127.0.0.1:3000/qqbot/webhook;
|
|
239
|
-
|
|
240
|
-
# 必要的代理头设置
|
|
241
|
-
proxy_set_header Host $host;
|
|
242
|
-
proxy_set_header X-Real-IP $remote_addr;
|
|
243
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
244
|
-
proxy_set_header X-Forwarded-Proto $scheme;
|
|
245
|
-
|
|
246
|
-
# 关键配置:保持原始请求体用于签名验证
|
|
247
|
-
proxy_buffering off;
|
|
248
|
-
proxy_request_buffering off;
|
|
249
|
-
proxy_read_timeout 300;
|
|
250
|
-
proxy_connect_timeout 300;
|
|
251
|
-
proxy_send_timeout 300;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
# 可选:为Karin的其他功能添加代理
|
|
255
|
-
location /karin/ {
|
|
256
|
-
proxy_pass http://127.0.0.1:3000/;
|
|
257
|
-
proxy_set_header Host $host;
|
|
258
|
-
proxy_set_header X-Real-IP $remote_addr;
|
|
259
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
260
|
-
proxy_set_header X-Forwarded-Proto $scheme;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
```
|
|
137
|
+
- 主动连接 QQ 官方 `wss://api.sgroup.qq.com/websocket/`
|
|
138
|
+
- 无需公网 IP / HTTPS 证书
|
|
139
|
+
- intents 自动探测,从最大权限位逐级回退到可用集合
|
|
140
|
+
- **自动 Resume**:断网时记录 `session_id` / `seq`,下次连接走 `op:6` 让服务端补发丢失的事件;服务端拒绝 Resume 时降级 Identify
|
|
141
|
+
- 指数退避重连:`1.5s × 2^n + jitter`,上限 30s
|
|
264
142
|
|
|
265
|
-
|
|
143
|
+
### Webhook(`event.type: 1`)
|
|
266
144
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
145
|
+
- QQ 主动推送 `POST /qqbot/webhook` 到你的服务
|
|
146
|
+
- 自动处理 `op:13` 鉴权回调(签名回包)
|
|
147
|
+
- 普通事件用 ed25519 校验签名
|
|
148
|
+
- 需要公网 HTTPS:在 QQ 开放平台后台配置「统一回调地址」为 `https://your-domain/qqbot/webhook`
|
|
271
149
|
|
|
272
|
-
|
|
273
|
-
sudo certbot --nginx -d your-domain.com
|
|
150
|
+
---
|
|
274
151
|
|
|
275
|
-
|
|
276
|
-
sudo certbot renew --dry-run
|
|
152
|
+
## 发送通道
|
|
277
153
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
# 添加以下行:
|
|
281
|
-
# 0 12 * * * /usr/bin/certbot renew --quiet
|
|
282
|
-
```
|
|
154
|
+
**所有 QQ / 频道消息一律走 `msg_type=2` Markdown 通道**(官方已全量开放),不再
|
|
155
|
+
按内容选择通道:
|
|
283
156
|
|
|
284
|
-
|
|
157
|
+
- 文本 / `segment.at(...)` 通过 markdown content 渲染(at 用 `<qqbot-at-user id="..."/>` 内嵌标签)
|
|
158
|
+
- 图片合并为 `` 内嵌到同一条 markdown
|
|
159
|
+
- `segment.button(...)` / `segment.keyboard(...)` 自动挂到 `keyboard.content.rows`,与 markdown 同条下发
|
|
160
|
+
- 文本中 URL(开启 `keyboard.enable` 时)自动 `extractUrlButtons` 转 keyboard 按钮
|
|
161
|
+
- 视频 / 语音 / 文件不能进 markdown,由 pipeline 自动以 `msg_type=7` 紧随 markdown 主消息**并发补发**
|
|
285
162
|
|
|
286
|
-
|
|
163
|
+
---
|
|
287
164
|
|
|
288
|
-
|
|
289
|
-
ssl_certificate /path/to/your/certificate.crt; # 证书文件
|
|
290
|
-
ssl_certificate_key /path/to/your/private.key; # 私钥文件
|
|
291
|
-
```
|
|
165
|
+
## 按钮回调(INTERACTION_CREATE)
|
|
292
166
|
|
|
293
|
-
|
|
294
|
-
```bash
|
|
295
|
-
# 创建软链接启用站点
|
|
296
|
-
sudo ln -s /etc/nginx/sites-available/karin-qqbot /etc/nginx/sites-enabled/
|
|
167
|
+
收到按钮点击时,适配器:
|
|
297
168
|
|
|
298
|
-
|
|
299
|
-
|
|
169
|
+
1. 立即 `PUT /interactions/{id}` `code=0` 回 ack,防止客户端 loading
|
|
170
|
+
2. 将事件转为对应场景的消息事件投递:
|
|
171
|
+
- `chat_type=0` → guild message
|
|
172
|
+
- `chat_type=1` → group message
|
|
173
|
+
- `chat_type=2` → friend message
|
|
174
|
+
3. 消息 elements 结构:
|
|
300
175
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
**4. 配置HTTPS(必需)**
|
|
309
|
-
|
|
310
|
-
> **⚠️ 重要:** QQ开放平台**强制要求**使用HTTPS协议和443端口,以下配置是**必需的**,不是可选的。
|
|
311
|
-
|
|
312
|
-
```nginx
|
|
313
|
-
server {
|
|
314
|
-
listen 443 ssl http2;
|
|
315
|
-
server_name your-domain.com;
|
|
316
|
-
|
|
317
|
-
# SSL证书配置(使用Let's Encrypt免费证书)
|
|
318
|
-
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
|
319
|
-
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
|
320
|
-
|
|
321
|
-
# 如果没有SSL证书,可以使用以下命令获取Let's Encrypt免费证书:
|
|
322
|
-
# sudo apt install certbot python3-certbot-nginx
|
|
323
|
-
# sudo certbot --nginx -d your-domain.com
|
|
324
|
-
|
|
325
|
-
# SSL优化配置
|
|
326
|
-
ssl_protocols TLSv1.2 TLSv1.3;
|
|
327
|
-
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
|
|
328
|
-
ssl_prefer_server_ciphers on;
|
|
329
|
-
|
|
330
|
-
location /qqbot/webhook {
|
|
331
|
-
proxy_pass http://127.0.0.1:3000/qqbot/webhook;
|
|
332
|
-
proxy_set_header Host $host;
|
|
333
|
-
proxy_set_header X-Real-IP $remote_addr;
|
|
334
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
335
|
-
proxy_set_header X-Forwarded-Proto $scheme;
|
|
336
|
-
|
|
337
|
-
# 保持原始请求体
|
|
338
|
-
proxy_buffering off;
|
|
339
|
-
proxy_request_buffering off;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
# HTTP自动跳转HTTPS(推荐配置)
|
|
344
|
-
server {
|
|
345
|
-
listen 80;
|
|
346
|
-
server_name your-domain.com;
|
|
347
|
-
return 301 https://$server_name$request_uri;
|
|
348
|
-
}
|
|
176
|
+
```ts
|
|
177
|
+
[
|
|
178
|
+
segment.at(selfId), // 群 / 单聊场景自动补
|
|
179
|
+
segment.text(button_data),
|
|
180
|
+
segment.json('{"tag":"qqbot-button-click","button_id":"...","button_data":"...",...}'),
|
|
181
|
+
// srcReply 末尾自动追加 segment.pasmsg(id, 'event')
|
|
182
|
+
]
|
|
349
183
|
```
|
|
350
184
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
**1. 创建网站**
|
|
354
|
-
- 域名:填写你的域名
|
|
355
|
-
- 根目录:可以是任意目录(不会用到)
|
|
356
|
-
|
|
357
|
-
**2. 配置SSL证书(必需)**
|
|
358
|
-
- 进入网站设置 → SSL
|
|
359
|
-
- 申请Let's Encrypt免费证书或上传自有证书
|
|
360
|
-
- 开启"强制HTTPS"
|
|
361
|
-
|
|
362
|
-
**3. 添加反向代理**
|
|
185
|
+
业务层通过 `e.rawEvent.t === 'INTERACTION_CREATE'` 区分普通消息与按钮点击。
|
|
363
186
|
|
|
364
|
-
|
|
187
|
+
---
|
|
365
188
|
|
|
366
|
-
|
|
367
|
-
- **代理名称:** Karin Service
|
|
368
|
-
- **目标URL:** `http://127.0.0.1:3000`
|
|
369
|
-
- **发送域名:** `$host`
|
|
370
|
-
- **代理目录:** `/`
|
|
371
|
-
|
|
372
|
-
**方式二:只代理webhook路径(推荐)**
|
|
373
|
-
- **代理名称:** QQBot Webhook
|
|
374
|
-
- **目标URL:** `http://127.0.0.1:3000/qqbot/webhook`
|
|
375
|
-
- **发送域名:** `$host`
|
|
376
|
-
- **代理目录:** `/qqbot/webhook`
|
|
377
|
-
|
|
378
|
-
> **推荐使用方式一**,这样整个域名都会指向您的Karin服务,QQ开放平台访问 `https://your-domain.com/qqbot/webhook` 时会被代理到 `http://127.0.0.1:3000/qqbot/webhook`。
|
|
379
|
-
|
|
380
|
-
**4. 高级设置**
|
|
381
|
-
添加以下配置到反向代理的配置文件中:
|
|
382
|
-
```nginx
|
|
383
|
-
proxy_buffering off;
|
|
384
|
-
proxy_request_buffering off;
|
|
385
|
-
```
|
|
189
|
+
## 群聊消息事件
|
|
386
190
|
|
|
387
|
-
|
|
191
|
+
QQ 官方 2026 起的新版 `GROUP_MESSAGE_CREATE` 报文:
|
|
388
192
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"op": 0, "t": "GROUP_MESSAGE_CREATE",
|
|
196
|
+
"d": {
|
|
197
|
+
"author": {
|
|
198
|
+
"id": "...", "member_openid": "...", "union_openid": "",
|
|
199
|
+
"username": "小布丁qwq", "bot": false
|
|
200
|
+
},
|
|
201
|
+
"content": " /分布 ",
|
|
202
|
+
"group_id": "...", "group_openid": "...",
|
|
203
|
+
"id": "ROBOT1.0_...",
|
|
204
|
+
"mentions": [
|
|
205
|
+
{ "is_you": true, "scope": "single", "username": "方舟生存飞升", "...": "..." }
|
|
206
|
+
],
|
|
207
|
+
"message_scene": { "ext": ["msg_idx=REFIDX_..."], "source": "default" },
|
|
208
|
+
"message_type": 0,
|
|
209
|
+
"timestamp": "2026-05-08T13:24:53+08:00"
|
|
210
|
+
}
|
|
405
211
|
}
|
|
406
212
|
```
|
|
407
213
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
**适用场景:** 没有公网IP,通过Cloudflare暴露服务
|
|
411
|
-
|
|
412
|
-
**1. 安装cloudflared**
|
|
413
|
-
```bash
|
|
414
|
-
# 下载并安装cloudflared
|
|
415
|
-
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
|
|
416
|
-
sudo dpkg -i cloudflared-linux-amd64.deb
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
**2. 登录Cloudflare**
|
|
420
|
-
```bash
|
|
421
|
-
cloudflared tunnel login
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
**3. 创建隧道**
|
|
425
|
-
```bash
|
|
426
|
-
cloudflared tunnel create karin-qqbot
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
**4. 配置DNS**
|
|
430
|
-
```bash
|
|
431
|
-
cloudflared tunnel route dns karin-qqbot your-subdomain.your-domain.com
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
**5. 运行隧道**
|
|
435
|
-
```bash
|
|
436
|
-
cloudflared tunnel run --url http://localhost:3000 karin-qqbot
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
#### 方案五:frp 内网穿透
|
|
440
|
-
|
|
441
|
-
**适用场景:** 使用自建或第三方frp服务
|
|
442
|
-
|
|
443
|
-
**客户端配置 (frpc.ini):**
|
|
444
|
-
```ini
|
|
445
|
-
[common]
|
|
446
|
-
server_addr = your-frp-server.com
|
|
447
|
-
server_port = 7000
|
|
448
|
-
token = your_token
|
|
449
|
-
|
|
450
|
-
[karin-qqbot]
|
|
451
|
-
type = http
|
|
452
|
-
local_ip = 127.0.0.1
|
|
453
|
-
local_port = 3000
|
|
454
|
-
custom_domains = your-domain.com
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
### 第六步:QQ开放平台回调地址要求
|
|
458
|
-
|
|
459
|
-
#### 官方限制条件
|
|
460
|
-
|
|
461
|
-
QQ开放平台对Webhook回调地址有以下**强制要求**:
|
|
462
|
-
|
|
463
|
-
| 要求项 | 限制 | 说明 |
|
|
464
|
-
|--------|------|------|
|
|
465
|
-
| **协议** | 必须HTTPS | 不支持HTTP协议 |
|
|
466
|
-
| **端口** | 必须443 | 不支持自定义端口(如:8080、:3000等) |
|
|
467
|
-
| **SSL证书** | 必须有效 | 需要被浏览器信任的证书 |
|
|
468
|
-
| **域名** | 必须有域名 | 不支持IP地址直接访问 |
|
|
469
|
-
| **响应时间** | 3秒内 | 超时会重试 |
|
|
470
|
-
|
|
471
|
-
#### 正确的回调地址格式
|
|
472
|
-
|
|
473
|
-
✅ **正确格式:**
|
|
474
|
-
- `https://your-domain.com/qqbot/webhook`
|
|
475
|
-
- `https://bot.your-company.com/qqbot/webhook`
|
|
476
|
-
|
|
477
|
-
❌ **错误格式:**
|
|
478
|
-
- `http://your-domain.com/qqbot/webhook` (不支持HTTP)
|
|
479
|
-
- `https://your-domain.com:3000/qqbot/webhook` (不支持自定义端口)
|
|
480
|
-
- `https://123.456.789.10/qqbot/webhook` (不支持IP地址)
|
|
481
|
-
|
|
482
|
-
### 第七步:域名和防火墙配置
|
|
483
|
-
|
|
484
|
-
#### 域名解析配置
|
|
485
|
-
|
|
486
|
-
确保域名正确解析到你的服务器:
|
|
487
|
-
```bash
|
|
488
|
-
# 检查域名解析
|
|
489
|
-
nslookup your-domain.com
|
|
490
|
-
dig your-domain.com
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
#### 防火墙配置
|
|
494
|
-
|
|
495
|
-
**Ubuntu/Debian (ufw):**
|
|
496
|
-
```bash
|
|
497
|
-
# 开放HTTP和HTTPS端口
|
|
498
|
-
sudo ufw allow 80
|
|
499
|
-
sudo ufw allow 443
|
|
500
|
-
|
|
501
|
-
# 如果直接暴露端口
|
|
502
|
-
sudo ufw allow 3000
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
**CentOS/RHEL (firewalld):**
|
|
506
|
-
```bash
|
|
507
|
-
# 开放端口
|
|
508
|
-
sudo firewall-cmd --permanent --add-port=80/tcp
|
|
509
|
-
sudo firewall-cmd --permanent --add-port=443/tcp
|
|
510
|
-
sudo firewall-cmd --reload
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
**云服务器安全组:**
|
|
514
|
-
- 阿里云:安全组规则添加入方向 80、443 端口
|
|
515
|
-
- 腾讯云:防火墙规则添加入站 80、443 端口
|
|
516
|
-
- AWS:Security Group 添加 HTTP、HTTPS 规则
|
|
214
|
+
适配器行为:
|
|
517
215
|
|
|
518
|
-
|
|
216
|
+
- 当 `mentions[].is_you === true` 时,elements 头部自动补 `segment.at(self)`
|
|
217
|
+
- `author.username` 写入 `sender.nick`
|
|
218
|
+
- `cfg.regex` 应用到 content 拆分后的每个文本段
|
|
219
|
+
- 原始报文完整保留在 `e.rawEvent`,业务层可访问 `mentions` / `message_scene` / `message_type`
|
|
519
220
|
|
|
520
|
-
|
|
521
|
-
|------|------|--------|
|
|
522
|
-
| `appId` | 机器人ID(必填) | "" |
|
|
523
|
-
| `secret` | 机器人密钥(必填) | "" |
|
|
524
|
-
| `sandbox` | 是否使用沙盒环境 | false |
|
|
525
|
-
| `qqEnable` | 是否启用QQ场景 | true |
|
|
526
|
-
| `guildEnable` | 是否启用频道场景 | true |
|
|
527
|
-
| `guildMode` | 频道模式(0公域,1私域) | 0 |
|
|
528
|
-
| `event.type` | 事件接收方式(0关闭,1webhook,2ws) | 0 |
|
|
221
|
+
---
|
|
529
222
|
|
|
530
|
-
|
|
223
|
+
## 撤回 / 引用回复 / 被动消息
|
|
531
224
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
| 4 | 纯文模板 | 多段文本消息 |
|
|
538
|
-
| 5 | 自定义处理 | 完全自定义逻辑 |
|
|
225
|
+
- **撤回**:`bot.recallMsg(contact, messageId)` —— 自动按场景调用 `/v2/users` / `/v2/groups` / `/channels` / `/dms`
|
|
226
|
+
- **引用回复**:传入 `segment.reply(messageId)`,仅附加在第一条消息上
|
|
227
|
+
- **被动消息白名单**:
|
|
228
|
+
- 单聊 `event_id` 接受:`INTERACTION_CREATE` / `C2C_MSG_RECEIVE` / `FRIEND_ADD`
|
|
229
|
+
- 群聊 `event_id` 接受:`INTERACTION_CREATE` / `GROUP_ADD_ROBOT` / `GROUP_MSG_RECEIVE`
|
|
539
230
|
|
|
540
|
-
|
|
231
|
+
---
|
|
541
232
|
|
|
542
|
-
|
|
233
|
+
## Web 配置面板
|
|
543
234
|
|
|
544
|
-
|
|
545
|
-
|---------|------|---------|
|
|
546
|
-
| `GROUP_AT_MESSAGE_CREATE` | 群聊@机器人消息 | `onGroupMsg` |
|
|
547
|
-
| `C2C_MESSAGE_CREATE` | C2C私聊消息 | `onFriendMsg` |
|
|
548
|
-
| `GUILD_MESSAGE_CREATE` | 频道消息 | `onChannelMsg` |
|
|
549
|
-
| `DIRECT_MESSAGE_CREATE` | 频道私信 | `onDirectMsg` |
|
|
235
|
+
Karin 内置 Web 面板可视化编辑 `config.json`,本插件提供以下控件:
|
|
550
236
|
|
|
551
|
-
|
|
237
|
+
- 基础字段:name / appId / secret / prodApi / sandboxApi / tokenApi
|
|
238
|
+
- 沙盒、QQ 场景、频道场景、频道私域模式开关
|
|
239
|
+
- 正则规则列表(每行 `<regex> <replacement>`)
|
|
240
|
+
- **URL 自动按钮** 开关(`keyboard.enable`)
|
|
241
|
+
- 事件接收方式(关闭 / Webhook / WebSocket)
|
|
552
242
|
|
|
553
|
-
|
|
243
|
+
---
|
|
554
244
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
#### 1. Webhook 方式
|
|
558
|
-
|
|
559
|
-
- **优点**:配置简单,不需要额外的中转服务
|
|
560
|
-
- **缺点**:需要有公网IP或域名
|
|
561
|
-
- **适用场景**:有固定服务器或云服务器的用户
|
|
562
|
-
|
|
563
|
-
配置完成后,需要在 QQ 开放平台配置 Webhook 回调地址。
|
|
564
|
-
|
|
565
|
-
#### 2. WebSocket 方式
|
|
566
|
-
|
|
567
|
-
- **优点**:适合内网环境,通过中转服务连接
|
|
568
|
-
- **缺点**:需要额外部署中转服务
|
|
569
|
-
- **适用场景**:没有公网IP的本地开发环境
|
|
570
|
-
|
|
571
|
-
### 发送模式说明
|
|
572
|
-
|
|
573
|
-
#### 模式 0:直接发送(推荐)
|
|
574
|
-
|
|
575
|
-
最简单的模式,直接发送纯文本和图片消息。
|
|
576
|
-
|
|
577
|
-
#### 模式 1:原生 Markdown
|
|
578
|
-
|
|
579
|
-
使用 QQ 官方的原生 Markdown 格式发送消息。
|
|
580
|
-
|
|
581
|
-
#### 模式 3:旧图文模板 Markdown
|
|
582
|
-
|
|
583
|
-
使用旧版图文混排模板,适合需要复杂排版的场景。
|
|
584
|
-
|
|
585
|
-
#### 模式 4:纯文模板 Markdown
|
|
586
|
-
|
|
587
|
-
使用纯文本模板,支持多个文本字段。
|
|
588
|
-
|
|
589
|
-
#### 模式 5:自定义处理
|
|
590
|
-
|
|
591
|
-
完全自定义消息处理逻辑。
|
|
592
|
-
|
|
593
|
-
## 开发指南
|
|
594
|
-
|
|
595
|
-
### 环境要求
|
|
596
|
-
|
|
597
|
-
- Node.js >= 16
|
|
598
|
-
- TypeScript >= 5.0
|
|
599
|
-
- Karin 框架
|
|
600
|
-
|
|
601
|
-
### 本地开发
|
|
602
|
-
|
|
603
|
-
1. 克隆仓库
|
|
245
|
+
## 开发
|
|
604
246
|
|
|
605
247
|
```bash
|
|
606
248
|
git clone https://github.com/KarinJS/karin-plugin-adapter-qqbot.git
|
|
607
249
|
cd karin-plugin-adapter-qqbot
|
|
250
|
+
pnpm install
|
|
251
|
+
pnpm dev # tsx watch
|
|
252
|
+
pnpm build # tsc + tsdown
|
|
608
253
|
```
|
|
609
254
|
|
|
610
|
-
2.
|
|
611
|
-
|
|
612
|
-
```bash
|
|
613
|
-
npm install
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
3. 开发模式运行
|
|
617
|
-
|
|
618
|
-
```bash
|
|
619
|
-
npm run dev
|
|
620
|
-
```
|
|
621
|
-
|
|
622
|
-
### 构建项目
|
|
623
|
-
|
|
624
|
-
项目使用 `tsup` 进行打包,同时会运行 `tsc` 进行类型检查。
|
|
625
|
-
|
|
626
|
-
```bash
|
|
627
|
-
npm run build
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
构建产物会输出到 `dist` 目录。
|
|
631
|
-
|
|
632
|
-
### 代码检查
|
|
633
|
-
|
|
634
|
-
```bash
|
|
635
|
-
npm run lint
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
### 发布
|
|
639
|
-
|
|
640
|
-
```bash
|
|
641
|
-
# 发布正式版
|
|
642
|
-
npm run pub
|
|
643
|
-
|
|
644
|
-
# 发布测试版
|
|
645
|
-
npm run pub-beta
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
## 项目结构
|
|
649
|
-
|
|
650
|
-
```
|
|
651
|
-
karin-plugin-adapter-qqbot/
|
|
652
|
-
├── src/
|
|
653
|
-
│ ├── connection/ # 连接层(WebSocket、Webhook、路由)
|
|
654
|
-
│ ├── core/ # 核心功能(适配器、事件处理、API)
|
|
655
|
-
│ ├── types/ # TypeScript 类型定义
|
|
656
|
-
│ └── utils/ # 工具函数
|
|
657
|
-
├── dist/ # 构建产物
|
|
658
|
-
├── config/ # 配置文件目录
|
|
659
|
-
├── package.json
|
|
660
|
-
├── tsconfig.json # TypeScript 配置
|
|
661
|
-
└── tsup.config.ts # 打包配置
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
## API 使用示例
|
|
665
|
-
|
|
666
|
-
### 发送群消息
|
|
255
|
+
源码结构(2.0):
|
|
667
256
|
|
|
668
|
-
```typescript
|
|
669
|
-
import type { AdapterQQBot } from '@karinjs/adapter-qqbot'
|
|
670
|
-
|
|
671
|
-
// 在你的插件中使用
|
|
672
|
-
export class MyPlugin extends plugin {
|
|
673
|
-
async handleGroupMessage(e: KarinMessage) {
|
|
674
|
-
const bot = e.bot as AdapterQQBot
|
|
675
|
-
// 发送消息
|
|
676
|
-
await bot.SendMessage(e.contact, [
|
|
677
|
-
{ type: 'text', text: 'Hello, World!' }
|
|
678
|
-
])
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
257
|
```
|
|
258
|
+
src/
|
|
259
|
+
├── connection/
|
|
260
|
+
│ ├── routing.ts express 路由聚合
|
|
261
|
+
│ ├── webhook.ts POST /qqbot/webhook
|
|
262
|
+
│ ├── transport.ts 事件总线(appId → 业务)
|
|
263
|
+
│ └── ws/
|
|
264
|
+
│ ├── client.ts 单连接生命周期 + 心跳 + Resume
|
|
265
|
+
│ ├── intents.ts intents 探测与回退
|
|
266
|
+
│ └── manager.ts 多 bot 连接管理
|
|
267
|
+
├── core/
|
|
268
|
+
│ ├── index.ts createBot / destroyBot / initQQBotAdapter
|
|
269
|
+
│ ├── api/ QQBotApi 门面 + http/messages/media/interaction/meta/builders
|
|
270
|
+
│ ├── internal/axios.ts access_token 缓存 + 自动刷新
|
|
271
|
+
│ ├── adapter/
|
|
272
|
+
│ │ ├── base.ts AdapterQQBot
|
|
273
|
+
│ │ ├── grouping.ts 消息归类
|
|
274
|
+
│ │ ├── pipeline-qq.ts QQ 单聊/群聊发送管线
|
|
275
|
+
│ │ ├── pipeline-guild.ts 频道发送管线
|
|
276
|
+
│ │ └── text-to-md.ts URL→ 按钮、图片→ markdown
|
|
277
|
+
│ ├── event/
|
|
278
|
+
│ │ ├── dispatcher.ts 事件分发器
|
|
279
|
+
│ │ ├── message.ts 群/单/频道/私信消息
|
|
280
|
+
│ │ ├── notice.ts 入退群/好友/主动消息开关
|
|
281
|
+
│ │ ├── interaction.ts 按钮回调
|
|
282
|
+
│ │ └── conver.ts 报文 → karin elements
|
|
283
|
+
│ └── onboard/
|
|
284
|
+
│ ├── crypto.ts AES-256-GCM 解密
|
|
285
|
+
│ ├── portal.ts q.qq.com 接口
|
|
286
|
+
│ ├── qr.ts 终端二维码 + 轮询
|
|
287
|
+
│ └── index.ts runQrOnboard / needQrOnboard
|
|
288
|
+
├── apps/ karin app 插件
|
|
289
|
+
│ └── login.ts #QQ登录 指令
|
|
290
|
+
├── types/ 事件、配置、opcode 类型
|
|
291
|
+
└── utils/ 日志、配置读写、文本工具
|
|
682
292
|
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
```typescript
|
|
686
|
-
await bot.recallMsg(e.contact, messageId)
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
## 常见问题
|
|
690
|
-
|
|
691
|
-
### 第十步:验证配置
|
|
692
|
-
|
|
693
|
-
#### 1. 检查配置文件
|
|
694
|
-
|
|
695
|
-
确保配置文件格式正确:
|
|
696
|
-
|
|
697
|
-
```bash
|
|
698
|
-
# 查看配置文件
|
|
699
|
-
cat @karinjs/@karinjs-adapter-qqbot/config/config.json
|
|
293
|
+
demo/ 示例 / 烟测 app(不进 npm 包,不自动加载)
|
|
294
|
+
└── qqtest.ts QQBot 2.0 真号烟测命令集合
|
|
700
295
|
```
|
|
701
296
|
|
|
702
|
-
|
|
297
|
+
### 调试
|
|
703
298
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
npm start
|
|
707
|
-
# 或者
|
|
708
|
-
node app.js
|
|
709
|
-
```
|
|
710
|
-
|
|
711
|
-
#### 3. 查看日志
|
|
712
|
-
|
|
713
|
-
检查日志文件,确认机器人连接成功:
|
|
714
|
-
|
|
715
|
-
```bash
|
|
716
|
-
# 查看最新日志
|
|
717
|
-
tail -f logs/error/*.log
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
正常情况下应该看到类似信息:
|
|
721
|
-
- `QQBot [AppID] 连接成功`
|
|
722
|
-
- `Webhook服务已启动,端口: 3000`
|
|
723
|
-
|
|
724
|
-
#### 4. 测试机器人
|
|
725
|
-
|
|
726
|
-
1. 将机器人邀请到测试群
|
|
727
|
-
2. 发送消息测试机器人响应
|
|
728
|
-
3. 检查日志确认消息接收正常
|
|
729
|
-
|
|
730
|
-
### 第十一步:常见问题排查
|
|
731
|
-
|
|
732
|
-
#### 问题1:Webhook接收不到消息
|
|
733
|
-
|
|
734
|
-
**检查清单:**
|
|
735
|
-
- [ ] QQ开放平台回调地址配置正确
|
|
736
|
-
- [ ] 服务器防火墙开放对应端口
|
|
737
|
-
- [ ] Nginx反向代理配置正确
|
|
738
|
-
- [ ] 域名解析正确指向服务器IP
|
|
739
|
-
|
|
740
|
-
**排查命令:**
|
|
741
|
-
```bash
|
|
742
|
-
# 检查端口是否监听
|
|
743
|
-
netstat -tlnp | grep :3000
|
|
744
|
-
|
|
745
|
-
# 检查防火墙状态
|
|
746
|
-
sudo ufw status
|
|
747
|
-
|
|
748
|
-
# 测试本地接口
|
|
749
|
-
curl -X POST http://localhost:3000/qqbot/webhook
|
|
750
|
-
```
|
|
751
|
-
|
|
752
|
-
#### 问题2:签名验证失败
|
|
753
|
-
|
|
754
|
-
**可能原因:**
|
|
755
|
-
- Secret配置错误
|
|
756
|
-
- 反向代理修改了请求体
|
|
757
|
-
- 时间戳差异过大
|
|
758
|
-
|
|
759
|
-
**解决方案:**
|
|
760
|
-
```nginx
|
|
761
|
-
# Nginx配置中添加
|
|
762
|
-
proxy_buffering off;
|
|
763
|
-
proxy_request_buffering off;
|
|
764
|
-
```
|
|
765
|
-
|
|
766
|
-
#### 问题3:消息发送失败
|
|
767
|
-
|
|
768
|
-
**检查清单:**
|
|
769
|
-
- [ ] AppID和Secret正确
|
|
770
|
-
- [ ] 机器人有发送消息权限
|
|
771
|
-
- [ ] API地址配置正确
|
|
772
|
-
- [ ] 网络连接正常
|
|
773
|
-
|
|
774
|
-
#### 问题4:频道消息收不到
|
|
775
|
-
|
|
776
|
-
**可能原因:**
|
|
777
|
-
- 频道机器人权限不足
|
|
778
|
-
- guildEnable配置为false
|
|
779
|
-
- 私域机器人未正确配置
|
|
780
|
-
|
|
781
|
-
**解决方案:**
|
|
782
|
-
```json
|
|
783
|
-
{
|
|
784
|
-
"guildEnable": true,
|
|
785
|
-
"guildMode": 1 // 私域机器人使用1
|
|
786
|
-
}
|
|
787
|
-
```
|
|
788
|
-
|
|
789
|
-
### 第十二步:进阶配置
|
|
790
|
-
|
|
791
|
-
#### 多机器人配置
|
|
792
|
-
|
|
793
|
-
```json
|
|
794
|
-
[
|
|
795
|
-
{
|
|
796
|
-
"appId": "机器人1的AppID",
|
|
797
|
-
"secret": "机器人1的Secret",
|
|
798
|
-
"event": { "type": 1 }
|
|
799
|
-
},
|
|
800
|
-
{
|
|
801
|
-
"appId": "机器人2的AppID",
|
|
802
|
-
"secret": "机器人2的Secret",
|
|
803
|
-
"event": { "type": 1 }
|
|
804
|
-
}
|
|
805
|
-
]
|
|
806
|
-
```
|
|
807
|
-
|
|
808
|
-
#### 环境分离配置
|
|
809
|
-
|
|
810
|
-
开发环境使用沙盒:
|
|
811
|
-
```json
|
|
812
|
-
{
|
|
813
|
-
"sandbox": true,
|
|
814
|
-
"sandboxApi": "https://sandbox.api.sgroup.qq.com"
|
|
815
|
-
}
|
|
816
|
-
```
|
|
817
|
-
|
|
818
|
-
生产环境使用正式API:
|
|
819
|
-
```json
|
|
820
|
-
{
|
|
821
|
-
"sandbox": false,
|
|
822
|
-
"prodApi": "https://api.sgroup.qq.com"
|
|
823
|
-
}
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
#### 消息过滤配置
|
|
827
|
-
|
|
828
|
-
```json
|
|
829
|
-
{
|
|
830
|
-
"exclude": [
|
|
831
|
-
"https://example.com",
|
|
832
|
-
"https://trusted-site.com"
|
|
833
|
-
],
|
|
834
|
-
"regex": [
|
|
835
|
-
{
|
|
836
|
-
"reg": "^/",
|
|
837
|
-
"rep": "#"
|
|
838
|
-
},
|
|
839
|
-
{
|
|
840
|
-
"reg": "\\[图片\\]",
|
|
841
|
-
"rep": ""
|
|
842
|
-
}
|
|
843
|
-
]
|
|
844
|
-
}
|
|
845
|
-
```
|
|
299
|
+
WS 入站消息、bus 派发、dispatcher 路由等关键链路均通过 `logger.debug` 输出。
|
|
300
|
+
诊断「事件收不到」类问题时,把 karin 的 `log.level` 改成 `debug` 即可看到完整链路。
|
|
846
301
|
|
|
847
|
-
|
|
302
|
+
---
|
|
848
303
|
|
|
849
|
-
|
|
304
|
+
## 从 1.x 升级
|
|
850
305
|
|
|
851
|
-
|
|
306
|
+
2.0 是破坏式重写,**不提供配置自动迁移**。需要手动调整:
|
|
852
307
|
|
|
853
|
-
|
|
308
|
+
| 1.x | 2.0 |
|
|
309
|
+
| --- | --- |
|
|
310
|
+
| `markdown.mode: 0/1/2/3/4/5`(模式选择 / 模板) | 全部删除,永远默认走 markdown 通道 |
|
|
311
|
+
| `event.wsUrl` / `event.wsToken` | 删除(中转方案已废弃) |
|
|
312
|
+
| 新增 | `keyboard.enable: true`(默认,URL 自动转按钮) |
|
|
854
313
|
|
|
855
|
-
|
|
314
|
+
完整改动详见 [CHANGELOG.md](./CHANGELOG.md) 2.0.0 段落。
|
|
856
315
|
|
|
857
|
-
|
|
316
|
+
---
|
|
858
317
|
|
|
859
|
-
##
|
|
318
|
+
## 反馈
|
|
860
319
|
|
|
861
|
-
-
|
|
862
|
-
- [QQ 机器人开放平台](https://bot.q.qq.com/)
|
|
863
|
-
- [QQ 机器人开发文档](https://bot.q.qq.com/wiki/)
|
|
320
|
+
- Issue:https://github.com/KarinJS/karin-plugin-adapter-qqbot/issues
|
|
864
321
|
|
|
865
|
-
|
|
322
|
+
---
|
|
866
323
|
|
|
867
|
-
|
|
324
|
+
## License
|
|
868
325
|
|
|
869
|
-
|
|
870
|
-
- 加入 Karin 开发者社群
|
|
326
|
+
MIT
|